﻿using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using JetBrains.Annotations;
using LightCAD.Core.Elements;
using LightCAD.MathLib;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using netDxf.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using static LightCAD.Core.Elements.LcPolyLine;

namespace LightCAD.Drawing.Actions
{
    public class TrimAction : ITransformDrawer
    {
        public static string CommandName;
        public static LcCreateMethod[] CreateMethods;
        static TrimAction()
        {
            CommandName = "TRIM";
            CreateMethods = new LcCreateMethod[1];
            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "TR",
                Description = "修剪",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep{Name = "Step0",Options = "TRIM选择对象或<全部选择>:"},
                    //new LcCreateStep{Name = "Step1",Options = "TRIM选择对象:"},
                    new LcCreateStep{Name = "Step1",Options = "TRIM[栏选(F)窗交(C)投影(P)边(E)删除(R)放弃(U)]:"},
                }
            };
        }
        protected DocumentRuntime docRt;
        protected ViewportRuntime vportRt;
        protected IDocumentEditor docEditor;
        protected ICommandControl commandCtrl;
        private ElementSetInputer ElementInputers { get; set; }
        private CmdTextInputer CmdTextInputer { get; set; }
        private PointInputer PointInputer { get; set; }
        private List<LcElement> selectedElements;
        private List<LcElement> selectedTrimResult;
        public List<Box2> boxes;
        List<LcElement> result = new List<LcElement>();
        public TrimAction()
        {

        }
        public TrimAction(IDocumentEditor docEditor)
        {
            this.docEditor = docEditor;
            this.docRt = docEditor.DocRt;
            this.vportRt = (docEditor as DrawingEditRuntime).ActiveViewportRt;
            this.commandCtrl = this.vportRt.CommandCtrl;
        }
        public async void ExecCreate(string[] args)
        {
            this.StartAction();
            var curMethod = CreateMethods[0];
            this.ElementInputers = new ElementSetInputer(this.docEditor);
            this.CmdTextInputer = new CmdTextInputer(this.docEditor);
            this.PointInputer = new PointInputer(this.docEditor);
        Step0:
            List<LcElement> InputElements = new List<LcElement>();
            var trim_step0 = curMethod.Steps[0];
            var trim_result0 = await ElementInputers.Execute(trim_step0.Options);
            if (ElementInputers.isCancelled)
            {
                this.Cancel();
                return;
            }
            this.selectedElements = new List<LcElement>();
            result.AddRange((List<LcElement>)trim_result0.ValueX);//选中的所有边界线
            selectedElements.AddRange((List<LcElement>)trim_result0.ValueX);
            if (selectedElements.Count > 0)
            {
                goto Step1;
            }
            else
            {
                goto Step0;
            }
        Step1:
            this.vportRt.SetTransformDrawer(this);
            this.vportRt.IsTrimAction = true;

            var trim_step1 = curMethod.Steps[1];
            var trim_result1 = await ElementInputers.Execute(trim_step1.Options);//不支持从左上到右下框选 因此利用盒子判断选中的带修剪的元素
            if (ElementInputers.isCancelled)
            {
                this.Cancel();
                return;
            }
            if (trim_result1 == null)
            {
                this.Cancel();
                return;
            }
            //最后一次框选的盒子
            Box2 box = this.vportRt.TrimBox2s[this.vportRt.TrimBox2s.Count - 1];
            //判断盒子与空间的什么元素相交 记录下来
            List<LcElement> lcElements = new List<LcElement>();
            lcElements = this.docRt.Document.ModelSpace.Elements.Where(x => x.IntersectWithBox(box.ToPolygon())).ToList();
            if (trim_result1.ValueX == null)
            {
                //else if(trim_result1.Option != null && trim_result1.Option == "F")
                //{
                //    goto Step2;
                //}
                //else if (trim_result1.Option != null && trim_result1.Option == "C")
                //{
                //    goto Step3;
                //}
                //else if (trim_result1.Option != null && trim_result1.Option == "P")
                //{
                //    goto Step4;
                //}
                //else if (trim_result1.Option != null && trim_result1.Option == "E")
                //{
                //    goto Step5;
                //}
                //else if (trim_result1.Option != null && trim_result1.Option == "R")
                //{
                //    goto Step6;
                //}
                //else (trim_result1.Option != null && trim_result1.Option == "U"){
                //    goto Step7;
                //}
            }
            this.selectedTrimResult = new List<LcElement>();
            // List<LcElement> result1 = (List<LcElement>)trim_result1.ValueX;
            foreach (var ele in lcElements)
            {
                if (!result.Contains(ele))
                {
                    selectedTrimResult.Add(ele);
                }
            }
            goto End;

        End:
            ExecuteTrim();
            this.vportRt.IsTrimAction = false;
            this.vportRt.TrimBox2s = new List<Box2>();
            this.EndAction();
        }
        List<LcElement> lcElements = new List<LcElement>();
        List<Vector2> intersectionPoint = new List<Vector2>();
        List<Vector2> intersectionPoint1 = new List<Vector2>();

        private void ExecuteTrim()
        {
            this.vportRt.TrimElements.Clear();
            for (int j = 0; j < selectedTrimResult.Count; j++)//遍历所有待修剪的线
            {
                Box2 box = this.vportRt.TrimBox2s[this.vportRt.TrimBox2s.Count - 1];
                LcElement trimline = selectedTrimResult[j];
                List<Vector2> intersectionPoints = new List<Vector2>();
                if (trimline is LcLine)//待修剪的线是直线
                {
                    LcLine LcLine = SortLineEndPoint(trimline);
                    intersectionPoints = GetValidCross(trimline, out List<LcElement> boundaryElements);

                    if (boundaryElements != null)
                    {
                        intersectionPoints.Add(LcLine.Start);
                        intersectionPoints.Add(LcLine.End);
                        List<LcLine> newlines = new List<LcLine>();
                        newlines = GetPartLine(intersectionPoints, box, out List<LcLine> lines);
                        if (newlines.Count == 0)
                        {
                            LcLine.Start = LcLine.Start;
                            LcLine.End = LcLine.End;
                        }
                        else
                        {
                            if (LcLine.Start == newlines[0].Start)
                            {
                                LcLine.Start = lines[newlines.Count].Start;
                                LcLine.End = LcLine.End;
                            }
                            else if (LcLine.End == newlines[newlines.Count - 1].End)
                            {
                                LcLine.Start = LcLine.Start;
                                LcLine.End = newlines[0].Start;

                            }
                            else
                            {
                                Vector2 pt = LcLine.End;
                                this.vportRt.ActiveElementSet.AddLine(newlines[newlines.Count - 1].End, pt);
                                LcLine.Start = LcLine.Start;
                                LcLine.End = newlines[0].Start;
                            }
                        }
                    }
                    else
                    {
                        LcLine.Start = LcLine.Start;
                        LcLine.End = LcLine.End;
                    }
                }
                if (trimline is LcCircle)
                {
                    LcCircle lcCircle = trimline as LcCircle;
                    //求出与圆相交的有效交点和边界
                    intersectionPoints = GetValidCross(trimline, out List<LcElement> boundaryElements);
                    List<Arc2d> drawArcList = new List<Arc2d>();
                    List<Vector2> validPoints = new List<Vector2>();
                    List<Vector2> validPoint = new List<Vector2>();
                    Arc2d arc2D = new Arc2d();
                    if (boundaryElements != null)
                    {
                        List<Arc2d> validArcList = CircleGetPartArc(intersectionPoints, lcCircle.Center, box, out List<Arc2d> arcList);
                        validPoints = GetArcValidPoint(validArcList, arcList);

                        //重新生成圆弧
                        for (int i = 0; i < validPoints.Count - 1; i++)
                        {
                            if (i != validPoints.Count - 2)
                            {
                                arc2D = Arc2d.CreatePCE(validPoints[i + 1], lcCircle.Center, validPoints[i + 2]);
                                i += 1;
                            }
                            else
                            {
                                arc2D = Arc2d.CreatePCE(validPoints[i + 1], lcCircle.Center, validPoints[0]);
                            }
                            var lcArc = this.docRt.Document.CreateObject<LcArc>();
                            lcArc.Center = arc2D.Center;
                            lcArc.Radius = arc2D.Radius;
                            lcArc.StartAngle = arc2D.StartAngle;
                            lcArc.EndAngle = arc2D.EndAngle;
                            lcArc.Startp = arc2D.Startp;
                            lcArc.Endp = arc2D.Endp;
                            lcArc.Midp = arc2D.Midp;
                            this.docRt.Document.ModelSpace.InsertElement(lcArc);
                        }
                        this.docRt.Document.ModelSpace.RemoveElement(trimline);
                    }
                }
                if (trimline is LcArc)
                {
                    LcArc arc = trimline as LcArc;
                    //求出与圆弧相交的有效交点和边界
                    intersectionPoints = GetValidCross(trimline, out List<LcElement> boundaryElements);
                    List<Vector2> validPoints = new List<Vector2>();
                    //重新生成圆弧
                    if (boundaryElements != null)
                    {
                        Circle2d ArcAsCircle = Circle2d.CreateCR(arc.Center, arc.Radius);
                        LcCircle lcCircle = new LcCircle();
                        Arc2d arc2D = new Arc2d();
                        lcCircle.Center = ArcAsCircle.Center;
                        lcCircle.Radius = ArcAsCircle.Radius;
                        //盒子框选的是哪部分圆弧
                        List<Arc2d> validArcList = ArcGetPartArc(intersectionPoints, lcCircle.Center, arc, box, out List<Arc2d> arcList);
                        List<Arc2d> ArcList = arcList;
                        validPoints = GetArcValidPoint(validArcList, ArcList);
                        //重新生成圆弧
                        for (int i = 0; i < validPoints.Count - 1; i++)
                        {
                            if (validPoints[i] != arc.Endp)
                            {
                                if (i + 1 != validPoints.Count - 1)
                                {
                                    arc2D = Arc2d.CreatePCE(validPoints[i + 1], lcCircle.Center, validPoints[i + 2]);
                                    i += 1;
                                }
                                else
                                {
                                    arc2D = Arc2d.CreatePCE(validPoints[i + 1], lcCircle.Center, validPoints[0]);
                                }

                            }
                            else
                            {
                                if (i + 1 == validPoints.Count - 1)
                                {
                                    arc2D = Arc2d.CreatePCE(validPoints[i + 1], lcCircle.Center, validPoints[0]);
                                }
                                else
                                {
                                    arc2D = Arc2d.CreatePCE(validPoints[i + 1], lcCircle.Center, validPoints[i + 2]);
                                    i += 1;
                                }
                            }
                            var lcArc = this.docRt.Document.CreateObject<LcArc>();
                            lcArc.Center = arc2D.Center;
                            lcArc.Radius = arc2D.Radius;
                            lcArc.StartAngle = arc2D.StartAngle;
                            lcArc.EndAngle = arc2D.EndAngle;
                            lcArc.Startp = arc2D.Startp;
                            lcArc.Endp = arc2D.Endp;
                            lcArc.Midp = arc2D.Midp;
                            this.docRt.Document.ModelSpace.InsertElement(lcArc);
                        }
                        this.docRt.Document.ModelSpace.RemoveElement(arc);
                    }
                }
                if (trimline is LcPolyLine)
                {
                    LcPolyLine lcPolyLine = trimline as LcPolyLine;
                    List<Tuple<Curve2d, List<Vector2>>> lp = GetPolylineSegmentsAndValidPoints(lcPolyLine);
                    List<List<Curve2d>> Segments = GetValidPolylineSegments(lp);
                    List<List<Curve2d>> NewSegments = new List<List<Curve2d>>();
                    NewSegments.AddRange(Segments);
                    //求出盒子框选的segments 并移除  直接判断元素与盒子相交的算法
                    for (int i = 0; i < Segments.Count; i++)
                    {
                        for (int u = 0; u < Segments[i].Count; u++)
                        {
                            Curve2d curve2D = Segments[i][u];
                            Box2 box1 = new Box2();
                            if (curve2D is Line2d)
                            {
                                Line2d line2 = curve2D as Line2d;
                                double minX = line2.Start.X < line2.End.X ? line2.Start.X : line2.End.X;
                                double maxX = line2.Start.X > line2.End.X ? line2.Start.X : line2.End.X;
                                double minY = line2.Start.Y < line2.End.Y ? line2.Start.Y : line2.End.Y;
                                double maxY = line2.Start.Y > line2.End.Y ? line2.Start.Y : line2.End.Y;
                                box1 = new Box2(minX, minY, maxX, maxY);
                            }
                            else
                            {
                                Arc2d arc2 = curve2D as Arc2d;
                                LcArc lcArc = new LcArc();
                                lcArc.Center = arc2.Center;
                                lcArc.Radius = arc2.Radius;
                                lcArc.StartAngle = arc2.StartAngle;
                                lcArc.EndAngle = arc2.EndAngle;
                                lcArc.Startp = arc2.Startp;
                                lcArc.Endp = arc2.Endp;
                                lcArc.Midp = arc2.Midp;
                                box1 = GetArcBoundingBox(lcArc);
                            }
                            if (box.IntersectsBox(box1))
                            {
                                NewSegments.Remove(Segments[i]);
                                continue;
                            }
                        }
                    }
                    List<Curve2d> curve2Ds = new List<Curve2d>();
                    foreach (List<Curve2d> curve2D in NewSegments)
                    {
                        foreach (Curve2d curve in curve2D)
                        {
                            curve2Ds.Add(curve);
                        }
                    }
                    CreatePolyLine(false, curve2Ds);
                    this.docRt.Document.ModelSpace.RemoveElement(lcPolyLine);
                }
            }
        }
        public void StartAction()
        {
            if (vportRt.CheckStatus(ViewportStatus.InAction))
            {
                vportRt.CancelCurrentAction();
            }
            vportRt.SetStatus(ViewportStatus.InAction);
            this.vportRt.CommandCenter.InAction = true;
        }
        public void DrawTrans(SKCanvas canvas)
        {
            var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
            Box2 drawBox = new Box2();
            this.vportRt.TrimElements = new List<LcElement>();
            //框选
            if (this.vportRt.CheckStatus(ViewportStatus.RectSelect))
            {
               //框选盒子
                var pressp = this.vportRt.PointerPressedPosition.ToVector2d();
                var wcs_pressp = this.vportRt.ConvertScrToWcs(pressp);
                double minX = wcs_mp.X < wcs_pressp.X ? wcs_mp.X : wcs_pressp.X;
                double maxX = wcs_mp.X > wcs_pressp.X ? wcs_mp.X : wcs_pressp.X;
                double minY = wcs_mp.Y < wcs_pressp.Y ? wcs_mp.Y : wcs_pressp.Y;
                double maxY = wcs_mp.Y > wcs_pressp.Y ? wcs_mp.Y : wcs_pressp.Y;
                drawBox = new Box2(minX, minY, maxX, maxY);
                
            }
            //点选
            if (!this.vportRt.CheckStatus(ViewportStatus.RectSelect))
            {
                //点选盒子的尺寸
                double selectSize = this.vportRt.ConvertScrToWcs(Constants.SelectBoxSize);
                drawBox = new Box2(new Vector2(wcs_mp.X - selectSize, wcs_mp.Y - selectSize), selectSize * 2, selectSize * 2);
            }
            //判断渲染的box框选的元素  此时没有执行第二步 因此没有待修剪的元素
            List<LcElement> lcElements = new List<LcElement>();
            lcElements = this.docRt.Document.ModelSpace.Elements.Where(x => x.IsSelected == false).ToList();//指定名为 x 的元素并返回当前状态为未被选中的元素
            SKPaint AuxPen = new SKPaint { Color = SKColors.Green, IsStroke = true, PathEffect = Constants.SelectedEffect };
            SKPaint AuxPen1 = new SKPaint { Color = SKColors.Gray, IsStroke = true, PathEffect = Constants.SelectedEffect };
            List<LcElement> trimElement = new List<LcElement>();
            List<LcElement> boundaryElements = new List<LcElement>();
            List<Vector2> validIntersectionPt = new List<Vector2>();
            //筛选出所有待被修剪的元素
            foreach (LcElement ele in lcElements)
            {
                if (ele.IntersectWithBox(drawBox.ToPolygon()))//说明此元素是待被修剪的元素
                {
                    trimElement.Add(ele);
                    this.vportRt.TrimElements.Add(ele);
                }
            }
            if (trimElement != null)
            {
                for (int i = 0; i < trimElement.Count; i++)
                {
                    if (trimElement[i] is LcLine)
                    {
                        //首尾点排序后的直线
                        LcLine lcLine = SortLineEndPoint(trimElement[i]);
                        //求出该修剪线与边界相交的有效交点
                        validIntersectionPt = GetValidCross(trimElement[i], out List<LcElement> boundaryElement);

                        if (boundaryElement != null)
                        {
                            validIntersectionPt.Add(lcLine.Start);
                            validIntersectionPt.Add(lcLine.End);
                            //求出与盒子相交的直线
                            List<LcLine> newlines = GetPartLine(validIntersectionPt, drawBox, out List<LcLine> lines);

                            if (newlines == null)
                            {
                                canvas.DrawLine(vportRt.ConvertWcsToScr(lcLine.Start).ToSKPoint(), vportRt.ConvertWcsToScr(lcLine.End).ToSKPoint(), AuxPen);
                            }
                            else
                            {
                                if (lcLine.Start == newlines[0].Start)
                                {
                                    canvas.DrawLine(vportRt.ConvertWcsToScr(lcLine.Start).ToSKPoint(), vportRt.ConvertWcsToScr(lines[newlines.Count - 1].End).ToSKPoint(), AuxPen1);
                                    canvas.DrawLine(vportRt.ConvertWcsToScr(lines[newlines.Count].Start).ToSKPoint(), vportRt.ConvertWcsToScr(lcLine.End).ToSKPoint(), AuxPen);
                                }
                                else if (lcLine.End == newlines[newlines.Count - 1].End)
                                {
                                    canvas.DrawLine(vportRt.ConvertWcsToScr(lcLine.Start).ToSKPoint(), vportRt.ConvertWcsToScr(newlines[0].Start).ToSKPoint(), AuxPen);
                                    canvas.DrawLine(vportRt.ConvertWcsToScr(newlines[0].Start).ToSKPoint(), vportRt.ConvertWcsToScr(lcLine.End).ToSKPoint(), AuxPen1);
                                }
                                else
                                {
                                    Vector2 pt = lcLine.End;
                                    canvas.DrawLine(vportRt.ConvertWcsToScr(newlines[newlines.Count - 1].End).ToSKPoint(), vportRt.ConvertWcsToScr(pt).ToSKPoint(), AuxPen);
                                    canvas.DrawLine(vportRt.ConvertWcsToScr(lcLine.Start).ToSKPoint(), vportRt.ConvertWcsToScr(newlines[0].Start).ToSKPoint(), AuxPen);
                                    canvas.DrawLine(vportRt.ConvertWcsToScr(newlines[0].Start).ToSKPoint(), vportRt.ConvertWcsToScr(newlines[newlines.Count - 1].End).ToSKPoint(), AuxPen1);

                                }
                            }
                        }
                    }
                    if (trimElement[i] is LcCircle)
                    {
                        LcCircle lcCircle = trimElement[i] as LcCircle;
                        //求出该修剪线与边界相交的有效交点
                        validIntersectionPt = GetValidCross(trimElement[i], out List<LcElement> boundaryElement);
                        //求出与盒子相交的圆弧
                        List<Arc2d> drawArcList = CircleGetPartArc(validIntersectionPt, lcCircle.Center, drawBox, out List<Arc2d> arcList);
                        //重新生成圆弧
                        List<Vector2> drawPoints = new List<Vector2>();
                        drawPoints = GetArcValidPoint(drawArcList, arcList);
                        Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));

                        //重新生成圆弧
                        for (int j = 0; j < drawPoints.Count - 1; j++)
                        {
                            Arc2d arc2D = new Arc2d();
                            if (j != drawPoints.Count - 2)
                            {
                                arc2D = Arc2d.CreatePCE(drawPoints[j + 1], lcCircle.Center, drawPoints[j + 2]);
                                j += 1;
                            }
                            else
                            {
                                arc2D = Arc2d.CreatePCE(drawPoints[i + 1], lcCircle.Center, drawPoints[0]);
                            }
                            var lcArc = this.docRt.Document.CreateObject<LcArc>();
                            lcArc.Center = arc2D.Center;
                            lcArc.Radius = arc2D.Radius;
                            lcArc.StartAngle = arc2D.StartAngle;
                            lcArc.EndAngle = arc2D.EndAngle;
                            lcArc.Startp = arc2D.Startp;
                            lcArc.Endp = arc2D.Endp;
                            lcArc.Midp = arc2D.Midp;
                            this.vportRt.DrawArc(arc2D, matrix, canvas, AuxPen);
                        }
                        for (int j = 0; j < drawPoints.Count - 1; j += 2)
                        {
                            Arc2d arc2D = Arc2d.CreatePCE(drawPoints[j], lcCircle.Center, drawPoints[j + 1]);
                            var lcArc = this.docRt.Document.CreateObject<LcArc>();
                            lcArc.Center = arc2D.Center;
                            lcArc.Radius = arc2D.Radius;
                            lcArc.StartAngle = arc2D.StartAngle;
                            lcArc.EndAngle = arc2D.EndAngle;
                            lcArc.Startp = arc2D.Startp;
                            lcArc.Endp = arc2D.Endp;
                            lcArc.Midp = arc2D.Midp;
                            this.vportRt.DrawArc(arc2D, matrix, canvas, AuxPen1);
                        }
                    }
                    if (trimElement[i] is LcArc)
                    {
                        LcArc arc = trimElement[i] as LcArc;
                        //求出与圆弧相交的有效交点和边界
                        validIntersectionPt = GetValidCross(trimElement[i], out List<LcElement> boundaryElement);
                        List<Vector2> validPoints = new List<Vector2>();
                        List<Vector2> trimValidPoints = new List<Vector2>();
                        Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                        //重新生成圆弧
                        if (boundaryElements != null)
                        {
                            Circle2d ArcAsCircle = Circle2d.CreateCR(arc.Center, arc.Radius);
                            LcCircle lcCircle = new LcCircle();
                            Arc2d arc2D = new Arc2d();
                            Arc2d trimArc2D = new Arc2d();
                            lcCircle.Center = ArcAsCircle.Center;
                            lcCircle.Radius = ArcAsCircle.Radius;
                            //盒子框选的是哪部分圆弧
                            List<Arc2d> validArcList = ArcGetPartArc(validIntersectionPt, lcCircle.Center, arc, drawBox, out List<Arc2d> arcList);
                            List<Arc2d> ArcList = arcList;
                            validPoints = GetArcValidPoint(validArcList, ArcList);
                            List<LcArc> lcArcs = new List<LcArc>();
                            //重新生成圆弧
                            for (int k = 0; k < validPoints.Count - 1; k++)
                            {
                                if (validPoints[k] != arc.Endp)
                                {
                                    if (k + 1 != validPoints.Count - 1)
                                    {
                                        arc2D = Arc2d.CreatePCE(validPoints[k + 1], arc.Center, validPoints[k + 2]);
                                        k += 1;
                                    }
                                    else
                                    {
                                        arc2D = Arc2d.CreatePCE(validPoints[k + 1], arc.Center, validPoints[0]);
                                    }

                                }
                                else
                                {
                                    if (k + 1 == validPoints.Count - 1)
                                    {
                                        arc2D = Arc2d.CreatePCE(validPoints[k + 1], arc.Center, validPoints[0]);
                                    }
                                    else
                                    {
                                        arc2D = Arc2d.CreatePCE(validPoints[k + 1], arc.Center, validPoints[k + 2]);
                                        k += 1;
                                    }

                                }
                                LcArc lcArc = new LcArc();
                                using (var elePen = new SKPaint { Color = SKColors.Green, IsStroke = true })
                                {
                                    this.vportRt.DrawArc(arc2D, matrix, canvas, elePen);
                                }
                            }
                            //重新绘制修剪的圆弧
                            trimValidPoints = GetTrimArcValidPoint(validArcList);
                            for (int k = 0; k < trimValidPoints.Count - 1; k++)
                            {
                                if (trimValidPoints.Count == 2)
                                {
                                    trimArc2D = Arc2d.CreatePCE(trimValidPoints[1], arc.Center, trimValidPoints[0]);
                                }
                                else
                                {
                                    if (k + 1 != trimValidPoints.Count - 1)
                                    {
                                        trimArc2D = Arc2d.CreatePCE(trimValidPoints[k + 1], arc.Center, trimValidPoints[k + 2]);
                                        k++;
                                    }
                                    else
                                    {
                                        trimArc2D = Arc2d.CreatePCE(trimValidPoints[k + 1], arc.Center, trimValidPoints[0]);
                                    }

                                }
                                using (var elePen = new SKPaint { Color = SKColors.Gray, IsStroke = true })
                                {
                                    this.vportRt.DrawArc(trimArc2D, matrix, canvas, elePen);
                                }
                            }

                        }

                    }
                    if (trimElement[i] is LcPolyLine)
                    {
                        LcPolyLine drawPolyline = trimElement[i] as LcPolyLine;
                        //取出多段线的每段元素以及元素上存在的有效交点
                        List<Tuple<Curve2d, List<Vector2>>> lp = GetPolylineSegmentsAndValidPoints(drawPolyline);
                        List<List<Curve2d>> Segments = GetValidPolylineSegments(lp);
                        List<List<Curve2d>> NewSegments = new List<List<Curve2d>>();
                        List<List<Curve2d>> TrimSegments = new List<List<Curve2d>>();
                        NewSegments.AddRange(Segments);
                        //求出盒子框选的segments并移除  直接判断元素与盒子相交的算法
                        for (int m = 0; m < Segments.Count; m++)
                        {
                            for (int u = 0; u < Segments[m].Count; u++)
                            {
                                Curve2d curve2D = Segments[m][u];
                                Box2 box1 = new Box2();
                                if (curve2D is Line2d)
                                {
                                    Line2d line2 = curve2D as Line2d;
                                    double minX1 = line2.Start.X < line2.End.X ? line2.Start.X : line2.End.X;
                                    double maxX1 = line2.Start.X > line2.End.X ? line2.Start.X : line2.End.X;
                                    double minY1 = line2.Start.Y < line2.End.Y ? line2.Start.Y : line2.End.Y;
                                    double maxY1 = line2.Start.Y > line2.End.Y ? line2.Start.Y : line2.End.Y;
                                    box1 = new Box2(minX1, minY1, maxX1, maxY1);
                                }
                                else
                                {
                                    Arc2d arc2 = curve2D as Arc2d;
                                    LcArc lcArc = new LcArc();
                                    lcArc.Center = arc2.Center;
                                    lcArc.Radius = arc2.Radius;
                                    lcArc.StartAngle = arc2.StartAngle;
                                    lcArc.EndAngle = arc2.EndAngle;
                                    lcArc.Startp = arc2.Startp;
                                    lcArc.Endp = arc2.Endp;
                                    lcArc.Midp = arc2.Midp;
                                    box1 = GetArcBoundingBox(lcArc);
                                }
                                if (drawBox.IntersectsBox(box1))
                                {
                                    TrimSegments.Add(Segments[m]);
                                    NewSegments.Remove(Segments[m]);
                                    break;
                                }
                            }
                        }
                        foreach (List<Curve2d> curve2D in NewSegments)
                        {
                            SKPoint start = new SKPoint();
                            SKPoint end = new SKPoint();
                            foreach (Curve2d ele in curve2D)
                            {
                                if (ele.Type == Curve2dType.Line2d)
                                {
                                    start = this.vportRt.ConvertWcsToScr((ele as Line2d).Start).ToSKPoint();
                                    end = this.vportRt.ConvertWcsToScr((ele as Line2d).End).ToSKPoint();
                                    canvas.DrawLine(start, end, AuxPen);
                                }
                                else if (ele.Type == Curve2dType.Arc2d)
                                {
                                    Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                                    using (var elePen = new SKPaint { Color = SKColors.Green, IsStroke = true })
                                    {
                                        this.vportRt.DrawArc(ele as Arc2d, matrix, canvas, elePen);
                                    }
                                }
                            }
                        }
                        foreach (List<Curve2d> curve2D in TrimSegments)
                        {
                            SKPoint start = new SKPoint();
                            SKPoint end = new SKPoint();
                            foreach (Curve2d ele in curve2D)
                            {
                                if (ele.Type == Curve2dType.Line2d)
                                {
                                    start = this.vportRt.ConvertWcsToScr((ele as Line2d).Start).ToSKPoint();
                                    end = this.vportRt.ConvertWcsToScr((ele as Line2d).End).ToSKPoint();
                                    canvas.DrawLine(start, end, AuxPen1);
                                }
                                else if (ele.Type == Curve2dType.Arc2d)
                                {
                                    Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                                    using (var elePen = new SKPaint { Color = SKColors.Gray, IsStroke = true })
                                    {
                                        this.vportRt.DrawArc(ele as Arc2d, matrix, canvas, elePen);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 取出多段线的每段元素以及元素上存在的有效交点
        /// </summary>
        /// <param name="lcPolyLine"></param>
        /// <returns></returns>
        private List<Tuple<Curve2d, List<Vector2>>> GetPolylineSegmentsAndValidPoints(LcPolyLine lcPolyLine)
        {
            List<Vector2> validPoint = new List<Vector2>();
            List<Tuple<Curve2d, List<Vector2>>> lp = new List<Tuple<Curve2d, List<Vector2>>>();
            foreach (Curve2d curve2D in lcPolyLine.Curve2ds)
            {
                if (curve2D is Line2d)
                {
                    Line2d line2D = curve2D as Line2d;
                    LcLine lcLine = new LcLine();
                    lcLine.Start = line2D.Start;
                    lcLine.End = line2D.End;
                    validPoint = GetValidCross(lcLine, out List<LcElement> boundaryElements);
                    lp.Add(new Tuple<Curve2d, List<Vector2>>(line2D, validPoint));
                }
                else
                {
                    Arc2d arc2D = curve2D as Arc2d;
                    LcArc lcArc = new LcArc();
                    lcArc.Startp = arc2D.Startp;
                    lcArc.Endp = arc2D.Endp;
                    lcArc.Center = arc2D.Center;
                    lcArc.Radius = arc2D.Radius;
                    lcArc.StartAngle = arc2D.StartAngle;
                    lcArc.EndAngle = arc2D.EndAngle;
                    lcArc.Midp = arc2D.Midp;
                    validPoint = GetValidCross(lcArc, out List<LcElement> boundaryElements);
                    lp.Add(new Tuple<Curve2d, List<Vector2>>(arc2D, validPoint));
                }
            }
            return lp;
        }
        /// <summary>
        /// 分割后的多段线
        /// </summary>
        /// <param name="lp"></param>
        /// <returns></returns>
        private List<List<Curve2d>> GetValidPolylineSegments(List<Tuple<Curve2d, List<Vector2>>> lp)
        {
            List<List<Curve2d>> Segments = new List<List<Curve2d>>();
            //判断交点数量，根据交点分割每段Curve
            for (int i = 0; i < lp.Count; i++)
            {

                if (lp[i].Item2.Count != 0)
                {
                    Curve2d curve = lp[i].Item1;
                    Vector2 curveStart, curveEnd;
                    if (lp[i].Item1 is Line2d)
                    {
                        curveStart = (lp[i].Item1 as Line2d).Start;
                        curveEnd = (lp[i].Item1 as Line2d).End;
                    }
                    else
                    {
                        curveStart = (lp[i].Item1 as Arc2d).Startp;
                        curveEnd = (lp[i].Item1 as Arc2d).Endp;
                    }
                    List<Vector2> validPoints = new List<Vector2>();
                    validPoints.AddRange(lp[i].Item2);
                    for (int k = 0; k < validPoints.Count; k++)
                    {
                        if (validPoints[k] == curveStart || validPoints[k] == curveEnd)
                        {
                            validPoints.Remove(validPoints[k]);
                        }
                    }
                    if (validPoints.Count != 0)
                    {
                        List<Tuple<Vector2, double>> linePoints = new List<Tuple<Vector2, double>>();
                        int count = 0;
                        for (int m = 0; m < i; m++)
                        {
                            count += lp[m].Item2.Count;//判断该元素之前的元素有几个交点
                        }
                        if (lp[i].Item1 is Line2d)
                        {
                            Vector2 lineStart = (lp[i].Item1 as Line2d).Start;
                            //计算每个点与起点的距离
                            //按照距离对点进行排序
                            foreach (Vector2 point in lp[i].Item2)
                            {
                                double distance = Math.Sqrt(Math.Pow((lineStart.X - point.X), 2) + Math.Pow((lineStart.Y - point.Y), 2));
                                linePoints.Add(new Tuple<Vector2, double>(point, distance));
                            }
                            List<Vector2> lineSortPoints = linePoints.OrderBy(x => x.Item2).Select(x => x.Item1).ToList();

                            Line2d line2D = lp[i].Item1 as Line2d;
                            for (int k = 0; k <= lineSortPoints.Count; k++)
                            {
                                Line2d p1 = new Line2d();
                                if (k == 0)
                                {
                                    p1.Start = line2D.Start;
                                    p1.End = lineSortPoints[k];
                                }
                                else
                                {
                                    if (k == lineSortPoints.Count)
                                    {
                                        p1.Start = lineSortPoints[k - 1];
                                        p1.End = line2D.End;
                                    }
                                    else
                                    {
                                        p1.Start = lineSortPoints[k - 1];
                                        p1.End = lineSortPoints[k];

                                    }
                                }
                                if (Segments.Count() > k + count)
                                {
                                    if (Segments[(k + count)] != null)
                                    {
                                        Segments[(k + count)].Add(p1);
                                    }
                                    else
                                    {
                                        Segments[(k + count)] = new List<Curve2d>();
                                        Segments[(k + count)].Add(p1);
                                    }
                                }
                                else
                                {
                                    List<Curve2d> Seg = new List<Curve2d>();
                                    Seg.Add(p1);
                                    Segments.Add(Seg);
                                }
                            }
                        }
                        else
                        {
                            Arc2d arc2D = lp[i].Item1 as Arc2d;
                            Vector2 center = arc2D.Center;
                            Vector2 drawStart = null;
                            Vector2 drawEnd = null;
                            Vector2 actualStart, actualEnd;
                            //首先取到实际画圆弧时的第一个点和第二个点
                            if (i + 1 < lp.Count)
                            {
                                if (lp[i + 1].Item1 is Line2d)
                                {
                                    drawStart = (lp[i + 1].Item1 as Line2d).Start;
                                    drawEnd = (lp[i + 1].Item1 as Line2d).End;
                                }
                                else
                                {
                                    drawStart = (lp[i + 1].Item1 as Arc2d).Startp;
                                    drawEnd = (lp[i + 1].Item1 as Arc2d).Endp;
                                }
                                if (arc2D.Startp.Equals(drawStart) || arc2D.Startp.Equals(drawEnd))
                                {
                                    actualStart = arc2D.Endp;
                                    actualEnd = arc2D.Startp;
                                }
                                else
                                {
                                    actualStart = arc2D.Startp;
                                    actualEnd = arc2D.Endp;
                                }

                            }
                            else
                            {
                                if (lp[i - 1].Item1 is Line2d)
                                {
                                    drawStart = (lp[i - 1].Item1 as Line2d).Start;
                                    drawEnd = (lp[i - 1].Item1 as Line2d).End;
                                }
                                else
                                {
                                    drawStart = (lp[i - 1].Item1 as Arc2d).Startp;
                                    drawEnd = (lp[i - 1].Item1 as Arc2d).Endp;
                                }
                                if (arc2D.Startp.Equals(drawStart) || arc2D.Startp.Equals(drawEnd))
                                {
                                    actualStart = arc2D.Startp;
                                    actualEnd = arc2D.Endp;
                                }
                                else
                                {
                                    actualStart = arc2D.Endp;
                                    actualEnd = arc2D.Startp;
                                }
                            }
                            List<Tuple<Vector2, double>> sortPoints = new List<Tuple<Vector2, double>>();
                            List<Vector2> sortPoint = new List<Vector2>();
                            sortPoint.Add(actualStart);
                            //计算实际开始与结束点的向量
                            //计算各点与实际开始点的向量
                            //计算向量的数量积 对所有交点进行排序
                            //加入实际起点和终点
                            double actualSX = actualStart.X;
                            double actualSY = actualStart.Y;
                            double actualEX = actualEnd.X;
                            double actualEY = actualEnd.Y;
                            double v1x = actualEX - actualSX;
                            double v1y = actualEY - actualSY;
                            foreach (Vector2 point in lp[i].Item2)
                            {
                                double interX = point.X;
                                double interY = point.Y;
                                double sInterX = interX - actualSX;
                                double sInterY = interY - actualSY;
                                double dotProduct = v1x * sInterX + v1y * sInterY;
                                sortPoints.Add(new Tuple<Vector2, double>(point, dotProduct));
                            }
                            List<Vector2> Points = sortPoints.OrderBy(p => p.Item2).Select(p => p.Item1).ToList();
                            foreach (Vector2 pt in Points)
                            {
                                sortPoint.Add(pt);
                            }
                            sortPoint.Add(actualEnd);
                            //重新生成时，判断弧线的走向 判断线的中点在实际起始线段的左侧还是右侧
                            //左侧 说明画弧时的走向与真正弧线的走向相反 右侧，则相同
                            Vector2 midp = arc2D.Midp;
                            int a = GeoUtils.IsTopInLine(actualStart, actualEnd, midp);
                            #region
                            //double sx = arc2D.Startp.X;
                            //double sy = arc2D.Startp.Y;
                            //double ex = arc2D.Endp.X;
                            //double ey = arc2D.Endp.Y;
                            //double v2x = sx - actualSX;
                            //double v2y = sy - actualSY;
                            //double v3x = ex - actualSX;
                            //double v3y = ey - actualSY;
                            //double dotProductSActual = v1x *v2x+ v1y *v2y;
                            //double dotProductEActual = v1x*v3x +v1y*v3y;

                            //sortPoints.Add(new Tuple<Vector2, double>(arc2D.Startp, dotProductSActual));
                            //sortPoints.Add(new Tuple<Vector2, double>(arc2D.Endp,dotProductEActual));
                            //List<Vector2> sortPoint = sortPoints.OrderBy(p => p.Item2).Select(p => p.Item1).ToList();
                            #endregion
                            #region
                            ////和实际画的起点 计算夹角
                            ////按照角度对所有交点排序
                            //foreach (Vector2 point in lp[i].Item2)
                            //{
                            //    double angle = GetDegreeByTwoLine1(center, arc2D.Startp, center, point);
                            //    linePoints.Add(new Tuple<Vector2, double>(point,angle));
                            //}
                            //List<Vector2> lineSortPoints = linePoints.OrderBy(x => x.Item2).Select(x => x.Item1).ToList();
                            #endregion
                            for (int k = 0; k < sortPoint.Count - 1; k++)
                            {
                                List<Vector2> points = new List<Vector2>();
                                Arc2d arc2 = new Arc2d();
                                if (a < 0)
                                {
                                    arc2 = Arc2d.CreatePCE(sortPoint[k + 1], center, sortPoint[k]);
                                }
                                else
                                {
                                    arc2 = Arc2d.CreatePCE(sortPoint[k], center, sortPoint[k + 1]);
                                }
                                #region
                                //if (k == 0)
                                //{
                                //    #region
                                //    //double angle = GetDegreeByTwoLine1(center, arc2D.Startp, center, actualStart);
                                //    //double angle1 = GetDegreeByTwoLine1(center, arc2D.Startp, center, sortPoint[0]);
                                //    //if (angle > angle1)
                                //    //{
                                //    //    arc2 = Arc2d.CreatePCE(sortPoint[0], center, actualStart);
                                //    //}
                                //    //else
                                //    //{
                                //    //    arc2 = Arc2d.CreatePCE(actualStart, center, sortPoint[0]);
                                //    //}

                                //    //double dotActualS = dotProduct(arc2D.Startp,arc2D.Endp,actualStart);
                                //    //double dotP0 = dotProduct(arc2D.Startp, arc2D.Endp, sortPoint[1]);
                                //    //if (dotActualS> dotP0)
                                //    //{
                                //    //    arc2 = Arc2d.CreatePCE(sortPoint[1], center, actualStart);
                                //    //}
                                //    //else
                                //    //{
                                //    //    arc2 = Arc2d.CreatePCE(actualStart, center, sortPoint[1]);
                                //    //}
                                //    #endregion
                                //    if (a<0)
                                //    {
                                //        arc2 = Arc2d.CreatePCE(sortPoint[1], center, sortPoint[0]);
                                //    }
                                //    else
                                //    {
                                //        arc2 = Arc2d.CreatePCE(sortPoint[0], center, sortPoint[1]);
                                //    }

                                //}
                                //else
                                //{
                                //    if (k == (sortPoint.Count-2))
                                //    {
                                //        #region
                                //        //double angle = GetDegreeByTwoLine1(center, arc2D.Startp, center, actualEnd);
                                //        //double angle1 = GetDegreeByTwoLine1(center, arc2D.Startp, center, sortPoint[k - 1]);
                                //        //if (angle > angle1)
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(sortPoint[k - 1], center, actualEnd);

                                //        //}
                                //        //else
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(actualEnd, center, sortPoint[k - 1]);
                                //        //}
                                //        //double dotActualS = dotProduct(arc2D.Startp, arc2D.Endp, actualEnd);
                                //        //double dotP0 = dotProduct(arc2D.Startp, arc2D.Endp, sortPoint[k]);
                                //        //if (dotActualS > dotP0)
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(sortPoint[k], center, actualEnd);
                                //        //}
                                //        //else
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(actualEnd, center, sortPoint[k]);
                                //        //}
                                //        #endregion
                                //        if (a < 0)
                                //        {
                                //            arc2 = Arc2d.CreatePCE(sortPoint[k + 1], center, sortPoint[k]);
                                //        }
                                //        else
                                //        {
                                //            arc2 = Arc2d.CreatePCE(sortPoint[k], center, sortPoint[k+1]);
                                //        }
                                //    }
                                //    else
                                //    {
                                //        #region
                                //        //double angle = GetDegreeByTwoLine1(center, arc2D.Startp, center, sortPoint[k - 1]);
                                //        //double angle1 = GetDegreeByTwoLine1(center, arc2D.Startp, center, sortPoint[k]);
                                //        //if (angle > angle1)
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(sortPoint[k], center, sortPoint[k - 1]);

                                //        //}
                                //        //else
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(sortPoint[k - 1], center, sortPoint[k]);
                                //        ////}
                                //        //double dotP0= dotProduct(arc2D.Startp, arc2D.Endp, sortPoint[k]);
                                //        //double dotP1 = dotProduct(arc2D.Startp, arc2D.Endp, sortPoint[k+1]);
                                //        //if (dotP1 > dotP0)
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(sortPoint[k], center, sortPoint[k+1]);
                                //        //}
                                //        //else
                                //        //{
                                //        //    arc2 = Arc2d.CreatePCE(sortPoint[k+1], center, sortPoint[k]);
                                //        //}
                                //        #endregion
                                //        if (a < 0)
                                //        {
                                //            arc2 = Arc2d.CreatePCE(sortPoint[k + 1], center, sortPoint[k]);
                                //        }
                                //        else
                                //        {
                                //            arc2 = Arc2d.CreatePCE(sortPoint[k], center, sortPoint[k + 1]);
                                //        }
                                //    }
                                //}
                                #endregion
                                if (Segments.Count() > k + count)
                                {
                                    if (Segments[(k + count)] != null)
                                    {
                                        Segments[(k + count)].Add(arc2);
                                    }
                                    else
                                    {
                                        Segments[(k + count)] = new List<Curve2d>();
                                        Segments[(k + count)].Add(arc2);
                                    }
                                }
                                else
                                {
                                    List<Curve2d> Seg = new List<Curve2d>();
                                    Seg.Add(arc2);
                                    Segments.Add(Seg);
                                }
                            }

                        }
                    }
                    else
                    {
                        if (i == 0)
                        {
                            List<Curve2d> Seg = new List<Curve2d>();
                            Seg.Add(curve);
                            Segments.Add(Seg);
                        }
                        else
                        {
                            int count = 0;
                            if (!lp[0].Item2.Contains(curveStart))
                            {
                                for (int m = 0; m < i; m++)
                                {
                                    count += lp[m].Item2.Count;
                                }
                                if (Segments.Count() > (count + 1) / 2)
                                {
                                    if (Segments[(count + 1) / 2] != null)
                                    {
                                        Segments[(count + 1) / 2].Add(lp[i].Item1);
                                    }
                                    else
                                    {
                                        Segments[(count + 1) / 2] = new List<Curve2d>();
                                        Segments[(count + 1) / 2].Add(lp[i].Item1);
                                    }
                                }
                                else
                                {
                                    List<Curve2d> Seg = new List<Curve2d>();
                                    Seg.Add(lp[i].Item1);
                                    Segments.Add(Seg);
                                }
                            }
                            else
                            {
                                for (int m = 0; m < i; m++)
                                {
                                    count += lp[m].Item2.Count;
                                }
                                if (Segments.Count() > (count) / 2)
                                {
                                    if (Segments[(count) / 2] != null)
                                    {
                                        Segments[(count) / 2].Add(lp[i].Item1);
                                    }
                                    else
                                    {
                                        Segments[(count) / 2] = new List<Curve2d>();
                                        Segments[(count) / 2].Add(lp[i].Item1);
                                    }
                                }
                                else
                                {
                                    List<Curve2d> Seg = new List<Curve2d>();
                                    Seg.Add(lp[i].Item1);
                                    Segments.Add(Seg);
                                }
                            }
                        }
                    }
                }
                else
                {
                    int count = 0;
                    for (int m = 0; m < i; m++)
                    {
                        count += lp[m].Item2.Count;
                    }
                    if (Segments.Count() > count)
                    {
                        if (Segments[(count)] != null)
                        {
                            Segments[(count)].Add(lp[i].Item1);
                        }
                        else
                        {
                            Segments[(count)] = new List<Curve2d>();
                            Segments[(count)].Add(lp[i].Item1);
                        }
                    }
                    else
                    {
                        List<Curve2d> Seg = new List<Curve2d>();
                        Seg.Add(lp[i].Item1);
                        Segments.Add(Seg);
                    }
                }
            }
            return Segments;
        }
        /// <summary>
        /// 求两个向量的数量积
        /// </summary>
        /// <param name="originalPS"></param>
        /// <param name="originalPE"></param>
        /// <param name="P"></param>
        /// <returns></returns>
        private double dotProduct(Vector2 originalPS, Vector2 originalPE, Vector2 P)
        {
            double x1 = originalPS.X;
            double y1 = originalPS.Y;
            double x2 = originalPE.X;
            double y2 = originalPE.Y;
            double x3 = P.X;
            double y3 = P.Y;
            double v1x = x2 - x1;
            double v1y = y2 - y1;
            double v2x = x3 - x1;
            double v2y = y3 - y1;
            double dotProduct = v1x * v2x + v1y * v2y;
            return dotProduct;
        }

        /// <summary>
        /// 求出待修剪线的有效边界和有效交点
        /// </summary>
        /// <param name="ele"></param>
        /// <returns></returns>
        private List<Vector2> GetValidCross(LcElement ele, out List<LcElement> boundaryElements)
        {
            List<LcElement> boundaryElement1 = new List<LcElement>();
            List<LcElement> boundaryElement2 = new List<LcElement>();
            List<Vector2> drawIntersectionPt = new List<Vector2>();
            List<Vector2> validIntersectionPt = new List<Vector2>();
            //求出与该修剪线相交的边界
            boundaryElement1 = result.Where(x => x.GetCrossVectorByElement(ele).Count != 0).ToList();
            //求出与该修剪线相交的有效边界及有效交点
            foreach (LcElement le in boundaryElement1)
            {
                drawIntersectionPt = le.GetCrossVectorByElement(ele);
                foreach (Vector2 pt in drawIntersectionPt)
                {
                    if (ele.PointInElement(pt) && le.PointInElement(pt))
                    {
                        boundaryElement2.Add(le);
                        break;
                    }
                }
                foreach (Vector2 pt in drawIntersectionPt)
                {
                    if (ele.PointInElement(pt) && le.PointInElement(pt))
                    {
                        validIntersectionPt.Add(pt);
                    }
                }
            }
            boundaryElements = boundaryElement2;
            return validIntersectionPt;
        }

        /// <summary>
        /// 判断框选的是哪部分直线
        /// </summary>
        /// <param name="intersectionPoints"></param>
        /// <param name="box"></param>
        /// <param name="lines"></param>
        /// <returns></returns>
        private List<LcLine> GetPartLine(List<Vector2> intersectionPoints, Box2 box, out List<LcLine> lines)
        {
            intersectionPoints = intersectionPoints.OrderBy(p => p.X).ThenBy(p => p.Y).ToList();//对所有交点排序
            List<Box2> boxes = new List<Box2>();
            List<LcLine> ls = new List<LcLine>();
            List<LcLine> newlines = new List<LcLine>();
            for (int i = 0; i < intersectionPoints.Count - 1; i++)
            {

                double minx = intersectionPoints[i].X < intersectionPoints[i + 1].X ? intersectionPoints[i].X : intersectionPoints[i + 1].X;
                double maxx = intersectionPoints[i].X > intersectionPoints[i + 1].X ? intersectionPoints[i].X : intersectionPoints[i + 1].X;
                double minY = intersectionPoints[i].Y < intersectionPoints[i + 1].Y ? intersectionPoints[i].Y : intersectionPoints[i + 1].Y;
                double maxY = intersectionPoints[i].Y > intersectionPoints[i + 1].Y ? intersectionPoints[i].Y : intersectionPoints[i + 1].Y;
                Box2 box1 = new Box2(minx, minY, maxx, maxY);
                boxes.Add(box1);
            }
            for (int i = 0; i < intersectionPoints.Count - 1; i++)
            {
                LcLine line = new LcLine();
                line.Start = intersectionPoints[i];
                line.End = intersectionPoints[i + 1];
                ls.Add(line);
            }
            lines = ls;
            for (int i = 0; i < boxes.Count; i++)
            {
                if (box.IntersectsBox(boxes[i]))
                {
                    newlines.Add(lines[i]);
                }
            }
            return newlines;
        }
        /// <summary>
        /// 判断框选的是哪部分圆弧
        /// </summary>
        /// <param name="intersectionPoints"></param>
        /// <param name="lcCircle"></param>
        /// <param name="box"></param>
        /// <param name="arcLis"></param>
        /// <returns></returns>
        private List<Arc2d> CircleGetPartArc(List<Vector2> intersectionPoints, Vector2 center, Box2 box, out List<Arc2d> arcList)
        {
            List<Arc2d> arcLis = new List<Arc2d>();
            List<Arc2d> validArcList = new List<Arc2d>();
            //对交点排序 按照与x轴的角度对点进行排序
            List<Vector2> crossPoints = SortCircleCross(intersectionPoints, center);
            //生成多段圆弧
            for (int i = 0; i < crossPoints.Count; i++)
            {
                Arc2d arc2d = new Arc2d();
                if (i == crossPoints.Count - 1)
                {
                    arc2d = Arc2d.CreatePCE(crossPoints[i], center, crossPoints[0]);
                }
                else
                {
                    arc2d = Arc2d.CreatePCE(crossPoints[i], center, crossPoints[i + 1]);
                }
                arcLis.Add(arc2d);
            }
            arcList = arcLis;
            //判断框选的盒子与哪些弧相交  只筛选与框选盒子相交的元素，包含在盒子里面的元素不被修剪
            for (int i = 0; i < arcList.Count; i++)
            {
                LcArc lcArc = new LcArc();
                lcArc.Center = arcList[i].Center;
                lcArc.Radius = arcList[i].Radius;
                lcArc.StartAngle = arcList[i].StartAngle;
                lcArc.EndAngle = arcList[i].EndAngle;
                lcArc.Startp = arcList[i].Startp;
                lcArc.Endp = arcList[i].Endp;
                lcArc.Midp = arcList[i].Midp;
                Box2 box2 = GetArcBoundingBox(lcArc);
                if (box2.IntersectsBox(box))//这个相交包含不包含  盒子包含元素这种情况
                {
                    //validPoints.Add(arcList[i].Startp);
                    //validPoints.Add(arcList[i].Endp);
                    validArcList.Add(arcList[i]);
                }
            }
            return validArcList;
        }
        private List<Arc2d> ArcGetPartArc(List<Vector2> intersectionPoints, Vector2 center, LcArc lcArc, Box2 box, out List<Arc2d> arcList)
        {
            List<Arc2d> arcLis = new List<Arc2d>();
            List<Arc2d> validArcList = new List<Arc2d>();
            intersectionPoints.Add(lcArc.Startp);
            intersectionPoints.Add(lcArc.Endp);
            //对交点排序 按照与x轴的角度对点进行排序
            List<Vector2> crossPoints = SortCircleCross(intersectionPoints, center);
            //生成多段圆弧
            for (int i = 0; i < crossPoints.Count; i++)
            {
                if (crossPoints[i] != lcArc.Endp)
                {
                    Arc2d arc2d = new Arc2d();
                    if (i == crossPoints.Count - 1)
                    {
                        arc2d = Arc2d.CreatePCE(crossPoints[i], center, crossPoints[0]);
                    }
                    else
                    {
                        arc2d = Arc2d.CreatePCE(crossPoints[i], center, crossPoints[i + 1]);
                    }
                    arcLis.Add(arc2d);
                }

            }
            arcList = arcLis;
            //判断框选的盒子与哪些弧相交  只筛选与框选盒子相交的元素，包含在盒子里面的元素不被修剪
            for (int i = 0; i < arcList.Count; i++)
            {
                LcArc lcArc1 = new LcArc();
                lcArc1.Center = arcList[i].Center;
                lcArc1.Radius = arcList[i].Radius;
                lcArc1.StartAngle = arcList[i].StartAngle;
                lcArc1.EndAngle = arcList[i].EndAngle;
                lcArc1.Startp = arcList[i].Startp;
                lcArc1.Endp = arcList[i].Endp;
                lcArc1.Midp = arcList[i].Midp;
                Box2 box2 = GetArcBoundingBox(lcArc1);
                if (box2.IntersectsBox(box))
                {
                    validArcList.Add(arcList[i]);
                }
            }
            return validArcList;
        }
        /// <summary>
        /// 对直线的首尾点进行排序
        /// </summary>
        /// <param name="trimline"></param>
        /// <returns></returns>
        private LcLine SortLineEndPoint(LcElement trimline)
        {
            LcLine LcLine = trimline as LcLine;
            List<Vector2> lineEndPoint = new List<Vector2>();
            lineEndPoint.Add(LcLine.Start);
            lineEndPoint.Add(LcLine.End);
            lineEndPoint = lineEndPoint.OrderBy(x => x.X).ThenBy(y => y.Y).ToList();
            LcLine.Start = lineEndPoint[0];
            LcLine.End = lineEndPoint[1];
            return LcLine;
        }
        /// <summary>
        /// 对圆弧或圆上的点进行排序
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        private List<Vector2> SortCircleCross(List<Vector2> points, Vector2 center)
        {
            Vector2 centerX = new(center.X + 500, center.Y);
            List<Tuple<Vector2, double>> ps = new List<Tuple<Vector2, double>>();
            for (int i = 0; i < points.Count; i++)
            {
                Vector2 pt = points[i];
                double includedAngle = GetDegreesByTwoLine(center, centerX, center, pt);
                //Tuple<Vector2, double> tuple = new Tuple<Vector2, double>(pt, includedAngle);
                ps.Add(new Tuple<Vector2, double>(pt, includedAngle));//元组
            }
            return ps.OrderBy(x => x.Item2).Select(x => x.Item1).ToList();
        }

        public void DrawLengthen(SKCanvas canvas)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 获取两条线段的夹角 前提是起点相同
        /// </summary>
        /// <param name="line1start"></param>
        /// <param name="line1End"></param>
        /// <param name="line2start"></param>
        /// <param name="line2End"></param>
        /// <returns></returns>
        public double GetDegreesByTwoLine(Vector2 line1start, Vector2 line1End, Vector2 line2start, Vector2 line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;

            // 计算线段的向量表示
            double v1x = x2 - x1;
            double v1y = y2 - y1;
            double v2x = x4 - x3;
            double v2y = y4 - y3;

            // 计算向量的内积
            double dotProduct = v1x * v2x + v1y * v2y;


            // 计算向量的长度
            double magnitudeV1 = Math.Sqrt(v1x * v1x + v1y * v1y);
            double magnitudeV2 = Math.Sqrt(v2x * v2x + v2y * v2y);
            double angleDegrees = Math.Acos(dotProduct / (magnitudeV1 * magnitudeV2)) * 180 / Math.PI;
            if (y4 < y1)
            {
                angleDegrees = 360 - angleDegrees;
            }
            return angleDegrees;
        }
        /// <summary>
        /// 获取未被修剪的圆弧的有效边界点
        /// </summary>
        /// <param name="validArcList"></param>
        /// <param name="ArcList"></param>
        /// <returns></returns>
        private List<Vector2> GetArcValidPoint(List<Arc2d> validArcList, List<Arc2d> ArcList)
        {
            List<Vector2> validPoints = new List<Vector2>();
            //Vector2 center = validArcList[0].Center;
            //生成新的弧 
            for (int i = 0; i < validArcList.Count; i++)
            {
                if (ArcList.Contains(validArcList[i]))
                {
                    ArcList.Remove(validArcList[i]);//取出未被框选到的圆弧
                }
            }

            //取出所有边界点
            for (int i = 0; i < ArcList.Count; i++)
            {
                if (i == ArcList.Count - 1)
                {
                    if (ArcList[i].Endp != ArcList[0].Startp)
                    {
                        validPoints.Add(ArcList[i].Endp);
                        validPoints.Add(ArcList[0].Startp);
                    }
                }
                else
                {
                    if (ArcList[i].Endp != ArcList[i + 1].Startp)
                    {
                        validPoints.Add(ArcList[i].Endp);
                        validPoints.Add(ArcList[i + 1].Startp);
                    }
                }
            }
            return validPoints;

        }
        /// <summary>
        /// 获取修剪线的有效边界点
        /// </summary>
        /// <param name="validArcList"></param>
        /// <returns></returns>
        private List<Vector2> GetTrimArcValidPoint(List<Arc2d> validArcList)
        {
            List<Vector2> validPoints = new List<Vector2>();
            //取出所有边界点
            for (int i = 0; i < validArcList.Count; i++)
            {
                if (i == validArcList.Count - 1)
                {
                    if (validArcList[i].Endp != validArcList[0].Startp)
                    {
                        validPoints.Add(validArcList[i].Endp);
                        validPoints.Add(validArcList[0].Startp);
                    }
                }
                else
                {
                    if (validArcList[i].Endp != validArcList[i + 1].Startp)
                    {
                        validPoints.Add(validArcList[i].Endp);
                        validPoints.Add(validArcList[i + 1].Startp);
                    }
                }
            }
            return validPoints;
        }
        /// <summary>
        /// 获取圆弧的包围盒
        /// </summary>
        /// <param name="lcArc"></param>
        /// <returns></returns>
        public Box2 GetArcBoundingBox(LcArc lcArc)
        {
            Vector2 centerX = new(lcArc.Center.X + 500, lcArc.Center.Y);
            double cMaxX = 0;
            double cMaxY = 0;
            double cMinX = 0;
            double cMinY = 0;
            double start = GetDegreesByTwoLine(lcArc.Center, centerX, lcArc.Center, lcArc.Startp);
            double end = GetDegreesByTwoLine(lcArc.Center, centerX, lcArc.Center, lcArc.Endp);
            double Radius = lcArc.Radius;
            if (start <= 90 && start >= 0 && end <= 90 && end >= 0) //起点端点都在    
            {
                if (start < end)
                {
                    cMaxX = lcArc.Startp.X;
                    cMinX = lcArc.Endp.X;
                    cMaxY = lcArc.Endp.Y;
                    cMinY = lcArc.Startp.Y;
                }
                if (end < start)
                {
                    cMaxY = lcArc.Center.Y + Radius;
                    cMinY = lcArc.Center.Y - Radius;
                    cMaxX = lcArc.Center.X + Radius;
                    cMinX = lcArc.Center.X - Radius;
                }
            }
            if (start > 90 && start <= 180 && end > 90 && end <= 180)
            {
                if (start < end)
                {
                    cMaxX = lcArc.Startp.X;
                    cMinX = lcArc.Endp.X;
                    cMinY = lcArc.Endp.Y;
                    cMaxY = lcArc.Startp.Y;
                }
                if (end < start)
                {
                    cMaxY = lcArc.Center.Y + Radius;
                    cMinY = lcArc.Center.Y - Radius;
                    cMaxX = lcArc.Center.X + Radius;
                    cMinX = lcArc.Center.X - Radius;
                }
            }
            if (start > 180 && start <= 270 && end > 180 && end <= 270)
            {
                if (start < end)
                {
                    cMinX = lcArc.Startp.X;
                    cMaxX = lcArc.Endp.X;
                    cMinY = lcArc.Endp.Y;
                    cMaxY = lcArc.Startp.Y;
                }
                if (end < start)
                {
                    cMaxY = lcArc.Center.Y + Radius;
                    cMinY = lcArc.Center.Y - Radius;
                    cMaxX = lcArc.Center.X + Radius;
                    cMinX = lcArc.Center.X - Radius;
                }
            }
            if (start > 270 && start <= 360 && end > 270 && end <= 360)
            {
                if (start < end)
                {
                    cMinX = lcArc.Startp.X;
                    cMaxX = lcArc.Endp.X;
                    cMaxY = lcArc.Endp.Y;
                    cMinY = lcArc.Startp.Y;
                }
                if (end < start)
                {
                    cMaxY = lcArc.Center.Y + Radius;
                    cMinY = lcArc.Center.Y - Radius;
                    cMaxX = lcArc.Center.X + Radius;
                    cMinX = lcArc.Center.X - Radius;
                }
            }
            if (start <= 90 && start >= 0 && end > 90 && end <= 180) //端点在第二象限 起点第一象限
            {
                cMaxX = lcArc.Startp.X;
                cMaxY = lcArc.Center.Y + Radius;
                cMinX = lcArc.Endp.X;
                if (lcArc.Startp.Y <= lcArc.Endp.Y)
                {
                    cMinY = lcArc.Startp.Y;
                }
                if (lcArc.Startp.Y > lcArc.Endp.Y)
                {
                    cMinY = lcArc.Endp.Y;
                }
            }
            if (start > 90 && start <= 180 && end <= 90 && end >= 0) //起点在第二象限，端点在第一象限
            {
                cMaxX = lcArc.Center.X + Radius;
                cMinX = lcArc.Center.X - Radius;
                cMinY = lcArc.Center.Y - Radius;
                if (lcArc.Startp.Y >= lcArc.Endp.Y)
                {
                    cMaxY = lcArc.Startp.Y;
                }
                else
                {
                    cMaxY = lcArc.Endp.Y;
                }
            }
            if (start <= 90 && start >= 0 && end > 180 && end <= 270) //起点第一象限，端点在第三象限
            {
                cMaxX = lcArc.Startp.X;
                cMaxY = lcArc.Center.Y + Radius;
                cMinX = lcArc.Center.X - Radius;
                cMinY = lcArc.Endp.Y;
            }
            if (start > 180 && start <= 270 && end > 0 && end <= 90) //起点在第三象限 端点在第一象限
            {
                cMaxX = lcArc.Center.X + Radius;
                cMinX = lcArc.Startp.X;
                cMaxY = lcArc.Endp.Y;
                cMinY = lcArc.Center.Y - Radius;
            }
            if (start <= 90 && start >= 0 && end > 270 && end <= 360)//起点在第一象限 端点在第四象限
            {
                if (lcArc.Startp.X >= lcArc.Endp.X)
                {
                    cMaxX = lcArc.Startp.X;
                }
                else
                {
                    cMaxX = lcArc.Endp.X;
                }
                cMaxY = lcArc.Center.Y + Radius;
                cMinX = lcArc.Center.X - Radius;
                cMinY = lcArc.Center.Y - Radius;
            }
            if (start > 270 && start <= 360 && end >= 0 && end <= 90) //起点在第四象限，端点在第一象限
            {
                cMaxX = lcArc.Center.X + Radius;
                if (lcArc.Startp.X <= lcArc.Endp.X)
                {
                    cMinX = lcArc.Startp.X;
                }
                else
                {
                    cMinX = lcArc.Endp.X;
                }
                cMaxY = lcArc.Endp.Y;
                cMinY = lcArc.Startp.Y;
            }
            if (start > 90 && start <= 180 && end > 180 && end <= 270) //起点第二象限，端点在第三象限
            {
                if (lcArc.Startp.X >= lcArc.Endp.X)
                {
                    cMaxX = lcArc.Startp.X;
                }
                else
                {
                    cMaxX = lcArc.Endp.X;
                }
                cMinX = lcArc.Center.X - Radius;
                cMinY = lcArc.Endp.Y;
                cMaxY = lcArc.Startp.Y;
            }
            if (start > 180 && start <= 270 && end > 90 && end <= 180) //起点第三象限，端点在第二象限
            {
                cMaxX = lcArc.Center.X + Radius;
                cMaxY = lcArc.Center.Y + Radius;
                if (lcArc.Startp.X <= lcArc.Endp.X)
                {
                    cMinX = lcArc.Startp.X;
                }
                else
                {
                    cMinX = lcArc.Endp.X;
                }
                cMinY = lcArc.Center.Y - Radius;
            }
            if (start > 90 && start <= 180 && end > 270 && end <= 360) //起点第二象限，端点在第四象限
            {
                cMaxX = lcArc.Endp.X;
                cMinX = lcArc.Center.X - Radius;
                cMaxY = lcArc.Startp.Y;
                cMinY = lcArc.Center.Y - Radius;
            }
            if (start > 270 && start <= 360 && end > 90 && end <= 180) //起点在第四象限，端点在第二象限
            {
                cMaxX = lcArc.Center.X + Radius;
                cMinX = lcArc.Endp.X;
                cMaxY = lcArc.Center.Y + Radius;
                cMinY = lcArc.Startp.Y;
            }
            if (start > 180 && start <= 270 && end > 270 && end <= 360) //起点在第三象限，端点在第四象限
            {
                cMaxX = lcArc.Endp.X;
                cMinX = lcArc.Startp.X;
                if (lcArc.Startp.Y >= lcArc.Endp.Y)
                {
                    cMaxY = lcArc.Startp.Y;
                }
                else
                {
                    cMaxY = lcArc.Endp.Y;
                }
                cMinY = lcArc.Center.Y - Radius;
            }
            if (start > 270 && start <= 360 && end > 180 && end <= 270) //起点在第四象限，端点在第三象限
            {
                cMaxX = lcArc.Center.X + Radius;
                cMinX = lcArc.Center.X - Radius;
                cMaxY = lcArc.Center.Y + Radius;
                if (lcArc.Startp.Y >= lcArc.Endp.Y)
                {
                    cMinY = lcArc.Endp.Y;
                }
                else
                {
                    cMinY = lcArc.Startp.Y;
                }
            }
            return new Box2().SetFromPoints(new Vector2(cMinX, cMinY), new Vector2(cMaxX, cMaxY));
        }
        /// <summary>
        /// 创建polyline
        /// </summary>
        /// <param name="isClosed"></param>
        /// <param name="Segments"></param>
        /// <returns></returns>
        private bool CreatePolyLine(bool isClosed, List<Curve2d> Segments)
        {
            var doc = this.docRt.Document;
            DocumentManager.CurrentRecorder.BeginAction("PolyLine");
            var PolyLine = doc.CreateObject<LcPolyLine>();
            PolyLine.IsClosed = isClosed;
            PolyLine.Curve2ds = Segments;
            doc.ModelSpace.InsertElement(PolyLine);
            this.docRt.Action.ClearSelects();
            DocumentManager.CurrentRecorder.EndAction();
            return true;
        }
        //public double GetDegreeByTwoLine1(Vector2 line1start, Vector2 line1End, Vector2 line2start, Vector2 line2End)
        //{
        //    //line1
        //    double x1 = line1start.X;
        //    double y1 = line1start.Y;
        //    double x2 = line1End.X;
        //    double y2 = line1End.Y;
        //    //line2
        //    double x3 = line2start.X;
        //    double y3 = line2start.Y;
        //    double x4 = line2End.X;
        //    double y4 = line2End.Y;
        //    //逆时针旋转90°的line1
        //    double x5 = line1start.X;
        //    double y5 = line1start.Y;
        //    double x6 = (x2 - x1) * 0 - ((y2 - y1) *1) + x1;
        //    double y6 = (y2 - y1) * 0 + ((x2 - x1) *1) + y1;
        //    // 计算线段的向量表示
        //    double v1x = x2 - x1;
        //    double v1y = y2 - y1;
        //    double v2x = x4 - x3;
        //    double v2y = y4 - y3;
        //    double v3x = x6 - x5;
        //    double v3y = y6 - y5;

        //    // 计算向量的内积
        //    double dotProductAB = v1x * v2x + v1y * v2y;
        //    double dotProductBC =  v3x *v2x+ v3y *v2y;

        //    // 计算向量的长度
        //    double magnitudeV1 = Math.Sqrt(v1x * v1x + v1y * v1y);
        //    double magnitudeV2 = Math.Sqrt(v2x * v2x + v2y * v2y);
        //    double angleDegrees = Math.Acos(dotProductAB /(magnitudeV1 * magnitudeV2))*180/ Math.PI;
        //    if (dotProductAB>0 )
        //    {
        //        if (dotProductBC < 0)
        //        {
        //            angleDegrees = (360 + angleDegrees)%360;
        //        }
        //    }
        //    else
        //    {
        //        if (dotProductBC < 0)
        //        {
        //            angleDegrees = (360 + angleDegrees)%360;
        //        }
        //    }
        //    return angleDegrees;
        //}

        public void Cancel()
        {
            this.DetachEvents();
            this.EndAction();
        }
        protected void DetachEvents()
        {

            //    vportRt.Control.DetachEvents(this.OnViewportMouseEvent, this.OnViewportKeyDown);
            //docRt.Commander.DetachInputEvent(OnInputKeyDown, OnInputKeyUp);
        }
        public void EndAction()
        {
            this.vportRt.SetTransformDrawer(null);
            vportRt.ClearStatus();
            this.commandCtrl.Prompt(string.Empty);

            this.vportRt.CurrentAction = null;
            this.vportRt.CursorType = LcCursorType.SelectElement;
            this.vportRt.CursorAddon = CursorAddonType.None;
            this.vportRt.CommandCenter.InAction = false;
            this.vportRt.CancelCurrentAction();
            if (this.docRt.Action.SelectedElements.Count > 0)
            {
                this.docRt.Action.SetSelectsToDragging(false);
                this.vportRt.ClearElementGrips();
                this.docRt.Action.ClearSelects();
            }
        }
    }
}
